#ifndef NLIST_H
#define NLIST_H

typedef struct _nlist_node_t {
    struct _nlist_node_t *prev;
    struct _nlist_node_t *next;
} nlist_node_t;

#define mnet_get_list_entry(node, type, member) ((type *)((char *)node - (unsigned long long)(&((type *)0)->member)))

static inline void nlist_node_init(nlist_node_t *node) {
    node->next = node->prev = node;
}

static inline nlist_node_t * nlist_node_next(nlist_node_t *node) {
    return node->next;
}

static inline nlist_node_t * nlist_node_prev(nlist_node_t *node) {
    return node->prev;
}

static inline void nlist_node_set_next(nlist_node_t *node, nlist_node_t *next_node) {
    next_node->next = node->next;
    next_node->prev = node;
    node->next->prev = next_node;
    node->next = next_node;
}

static inline void nlist_node_set_prev(nlist_node_t *node, nlist_node_t *prev_node) {
    prev_node->next = node;
    prev_node->prev = node->prev;
    node->prev->next = prev_node;
    node->prev = prev_node;
}

static inline void nlist_node_insert_tail(nlist_node_t *head_node, nlist_node_t *new_node) {
    head_node->prev->next = new_node;
    new_node->prev = head_node->prev;
    new_node->next = head_node;
    head_node->prev = new_node;
}

static inline int nlist_is_empty(nlist_node_t *node) {
    return (node->next == node);
}

static inline void nlist_node_remove(nlist_node_t *node) {
    node->next->prev = node->prev;
    node->prev->next = node->next;

    node->next = node->prev = node;
}

#endif